package org.lwjgltutorial.chapter3;

import static org.lwjgl.opengl.GL11.GL_LINE_LOOP;
import static org.lwjgl.opengl.GL11.GL_MODELVIEW;
import static org.lwjgl.opengl.GL11.GL_PROJECTION;
import static org.lwjgl.opengl.GL11.glBegin;
import static org.lwjgl.opengl.GL11.glEnd;
import static org.lwjgl.opengl.GL11.glFlush;
import static org.lwjgl.opengl.GL11.glLoadIdentity;
import static org.lwjgl.opengl.GL11.glMatrixMode;
import static org.lwjgl.opengl.GL11.glRotatef;
import static org.lwjgl.opengl.GL11.glVertex3f;

import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.util.glu.GLU;

public class RotatedSquare {

	public class CloseThread implements Runnable {

		@Override
		public void run() {
			// wait for close
			while(!Display.isCloseRequested()){
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}		
			}
			Display.destroy();
		}
	
	}

	private static final int WINDOW_HEIGHT = 600;
	private static final int WINDOW_WIDTH = 800;
	private boolean finished = false;
	
	public RotatedSquare(){
		init();
	}
	private void init() {
		// find out what the current bits per pixel of the desktop is
		int currentBpp = Display.getDisplayMode().getBitsPerPixel();
		// find a display mode at 800x600
		try {
			DisplayMode mode = findDisplayMode(WINDOW_WIDTH, WINDOW_HEIGHT,
					currentBpp);
			Display.setDisplayMode(mode);
			Display.setFullscreen(false);
			Display.setTitle("Rotated Square");
			Display.create();
		} catch (LWJGLException e) {
			e.printStackTrace();
		}
		
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		double aspectRatio = (double)WINDOW_WIDTH/WINDOW_HEIGHT;
		GLU.gluPerspective(
	            45.0f,        // Field Of View
	            (float)aspectRatio, // aspect ratio
	            0.001f,         // near Z clipping plane
	            10.0f);
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
		glRotatef(45f, 0, 0, -3);	
	}
	
	private void loop() {
		while(!finished   ){
			
			render();
			// update window.
			Display.update();
			// check if close requested
			if(Display.isCloseRequested())
				finished = true;
		}
		Display.destroy();
		
	}

	private void render() {
		// draw the square near to the viewer
		glBegin(GL_LINE_LOOP);
		glVertex3f(-0.5f, -0.5f, -3f);
		glVertex3f(-0.5f, 0.5f, -3f);
		glVertex3f(0.5f, 0.5f, -3f);
		glVertex3f(0.5f, -0.5f, -3f);
		glEnd();
		// flush any commands that are still hanging about.
		glFlush();
	}


	private DisplayMode findDisplayMode(int width, int height, int bpp) throws LWJGLException {
		DisplayMode[] modes = Display.getAvailableDisplayModes();
		DisplayMode mode = null;

		for (int i=0;i<modes.length;i++) {
			if ((modes[i].getBitsPerPixel() == bpp) || (mode == null)) {
				if ((modes[i].getWidth() == width) && (modes[i].getHeight() == height)) {
					mode = modes[i];
				}
			}
		}
		
		return mode;
	}

	public static void main(String[] args) throws InterruptedException{
		
		RotatedSquare square = new RotatedSquare();
		square.loop();
		
	}
}
